package com.mswyt.utils.msConverts;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.parseObject;

/**
 * 存放一些日常中常用的数据互转、数据拷贝等
 *
 * @author mahsuai
 * @ClassName: MsConvertDataUtils
 * @Description: 数据转换工具类
 */
public class MsConvertDataUtils {
    /**
     * -----------------------------------------------------------Map与对象的相互转换-------------------------------------------------------------------------------
     **/
    //TODO map转换为bean
    public static <T> T mapToBean(Map<String, Object> map, Class<T> tClass) {
        return parseObject(objToJsonStr(map), tClass, new Feature[0]);
    }

    //TODO bean转换map
    public static <T> Map<String, Object> beanToMap(T t) {
        return parseObject(objToJsonStr(t), Map.class);
    }

    //TODO List<Map>转换List<Bean>
    public static <T> List<T> listMapToListBean(List<Map<String, Object>> listMap, Class<T> tClass) {
        return listMap.stream().map(t -> parseObject(objToJsonStr(t), tClass, new Feature[0])).collect(Collectors.toList());
    }

    //TODO List<Bean>转换List<Map>
    public static <T> List<Map<String, Object>> listBeanToListMap(List<T> listBean) {
        return listBean.stream().map(t -> (Map<String, Object>) parseObject(objToJsonStr(t), Map.class)).collect(Collectors.toList());
    }

    //TODO 蒋String类型的{"one":"1","two":"2"},{"three":"3","four":"4"}转换成Map<String,Object>
    public static Map<String, Object> strToMap(String str) {
        return JSONObject.parseObject(str, new TypeReference<Map<String, Object>>() {
        });
    }

    /***
     * 对象转换成json字符串，保留空属性key
     * */
    public static String objToJsonStr(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 驼峰转带下划线的，比如userName=>user_name
     **/
    public static String camLToUnderline(String str) {
        Pattern compile = Pattern.compile("[A-Z]");
        Matcher matcher = compile.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串
     */
    public static String lineToCamel(String str) {
        // 快速检查
        if (str == null || str.isEmpty() || !str.contains("_")) {
            // 没必要转换
            return str;
        }
        StringBuilder sb = new StringBuilder();
        boolean flag = false;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == '_') {
                flag = true;
            } else {
                if (flag) {
                    sb.append(Character.toUpperCase(c));
                    flag = false;
                } else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }
        return sb.toString();
    }


    /**
     * 去除字符串最后一位数
     */
    public static String delStrLastDigitSymbol(String str) {
        if (StringUtils.isBlank(str)) return str;
        String newStr = str.substring(0, str.length() - 1);
        return newStr;
    }

    /**
     * double类型数字保留两位小数
     *
     * @param dou
     * @return 返回string
     * @author mashuai
     */

    public static String doubleKeepDecimalStr2(Double dou) {
        if (dou == null) return null;
        return String.format("%.2f", dou);
    }

    public static String doubleKeepDecimalStr3(Double dou) {
        if (dou == null) return null;
        return String.format("%.3f", dou);
    }

    /**
     * Double类型数字，保留小数
     *
     * @param dou      数字
     * @param newScale 保留的位数
     * @return 返回Double类型，如果结果是0.85格式，展示在前台会变成.85
     * @author mashuai
     */

    public static Double doubleKeepDecimal(Double dou, Integer newScale) {
        BigDecimal bigDecimal = new BigDecimal(dou).setScale(newScale, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }

    /**
     * 把一个list集合，按照指定len拆分。
     * 一般可以用于一个大的list，把他拆分成len组，每组单独丢入线程池中执行
     *
     * @param list
     * @param len
     * @return List<List>
     * @author mashuai
     */

    public static <T> List<List<T>> splitList(List<T> list, int len) {
        if (list == null || list.isEmpty() || len < 1) {
            return Collections.emptyList();
        }
        List<List<T>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<T> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 把集合ID拼接成('a1','a2'....)
     *
     * @author mashuai
     */
    public static String joinInSql(List collect) {
        StringBuilder sql = new StringBuilder();
        sql.append("  ( ");
        for (int i = 0; i < collect.size(); i++) {
            if (i < collect.size() - 1) {
                sql.append("'");
                sql.append(collect.get(i));
                sql.append("', ");
            } else {
                sql.append("'");
                sql.append(collect.get(i));
                sql.append("' ");
            }
        }
        sql.append(")");
        return sql.toString();
    }
}
